package edu.cuny.baruch.cis9590.library.gui;

import java.awt.CardLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collections;
import java.util.EnumMap;
import java.util.Map;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

import edu.cuny.baruch.cis9590.library.entities.Login;

public final class LibraryGUI extends JFrame {
    
    private final JMenu actionMenu;
    private final JMenuItem addBookMenuItem;
    private final JMenuItem patronSearchMenuItem;
    private final CardLayout cardLayout;
    private Login currentUser;
    
    protected enum Panel { BOOK_SEARCH, LOGIN, REGISTER, ADD_BOOK, PATRON_SEARCH }
    
    private final Map<Panel, LibraryPanel> panels = Collections.unmodifiableMap(new EnumMap<Panel, LibraryPanel>(Panel.class) {{
        put(Panel.BOOK_SEARCH, new BookSearchPanel(LibraryGUI.this));
        put(Panel.LOGIN, new LoginPanel(LibraryGUI.this));
        put(Panel.REGISTER, new RegisterPanel(LibraryGUI.this));
        put(Panel.ADD_BOOK, new AddBookPanel());
        put(Panel.PATRON_SEARCH, new PatronSearchPanel());
    }});
    
    public LibraryGUI() {
        setTitle("Library");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        JMenuBar menuBar = new JMenuBar();
        setJMenuBar(menuBar);
        
        JMenu fileMenu = new JMenu("File");
        menuBar.add(fileMenu);
        
        JMenuItem exitMenuItem = new JMenuItem("Exit");
        exitMenuItem.addActionListener(new ActionListener() {
            @Override public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        fileMenu.add(exitMenuItem);
        
        actionMenu = new JMenu("Actions");
        menuBar.add(actionMenu);
        
        JMenuItem bookSearchMenuItem = new JMenuItem("Book Search");
        bookSearchMenuItem.addActionListener(new ActionListener() {
            @Override public void actionPerformed(ActionEvent e) {
                changePanel(Panel.BOOK_SEARCH);
            }
        });
        actionMenu.add(bookSearchMenuItem);
        
        patronSearchMenuItem = new JMenuItem("Patron Search");
        patronSearchMenuItem.addActionListener(new ActionListener() {
            @Override public void actionPerformed(ActionEvent e) {
                changePanel(Panel.PATRON_SEARCH);
            }
        });
        actionMenu.add(patronSearchMenuItem);
        
        addBookMenuItem = new JMenuItem("Add Book");
        addBookMenuItem.addActionListener(new ActionListener() {
            @Override public void actionPerformed(ActionEvent e) {
                changePanel(Panel.ADD_BOOK);
            }
        });
        actionMenu.add(addBookMenuItem);
        
        JMenuItem logoutMenuItem = new JMenuItem("Logout");
        logoutMenuItem.addActionListener(new ActionListener() {
            @Override public void actionPerformed(ActionEvent e) {
                logout();
            }
        });
        actionMenu.add(logoutMenuItem);
        
        cardLayout = new CardLayout();
        getContentPane().setLayout(cardLayout);
        for (Map.Entry<Panel, LibraryPanel> panel : panels.entrySet()) {
            getContentPane().add(panel.getValue(), panel.getKey().toString());
        }
    }
    
    protected void changePanel(Panel panel) {
        panels.get(panel).clear();
        cardLayout.show(getContentPane(), panel.toString());
        pack();
    }
    
    protected Login getCurrentUser() {
        return currentUser;
    }
    
    protected void logout() {
        currentUser = null;
        setAccessLevel();
    }
    
    protected void login(Login login) {
        currentUser = login;
        setAccessLevel();
    }
    
    private void setAccessLevel() {
        int accessLevel = 0;
        if (currentUser != null) {
            accessLevel = currentUser.getAccessLevel();
        }
        switch (accessLevel) {
            case 3:
                addBookMenuItem.setVisible(true);
            case 2:
                patronSearchMenuItem.setVisible(true);
            case 1:
                changePanel(Panel.BOOK_SEARCH);
                actionMenu.setVisible(true);
                break;
            case 0:
                changePanel(Panel.LOGIN);
                actionMenu.setVisible(false);
                addBookMenuItem.setVisible(false);
                patronSearchMenuItem.setVisible(false);
                break;
        }
        for (LibraryPanel panel : panels.values()) {
            panel.setAccessLevel(accessLevel);
        }
    }
    
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override public void run() {
                try {
                    LibraryGUI frame = new LibraryGUI();
                    frame.setVisible(true);
                    frame.logout();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}
